package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import metier.Tache;

public class DaoTache implements IDao<Tache> {
	private Connection maCnx;
	/**
	 * Constructeur de la classe DaoFormationMySql
	 * Charge le pilote JDBC pour MySql et établit la connexion
	 * avec le serveur de données local (base test)
	 */
	public DaoTache()  {
		maCnx = null;
		try {
			   // on charge le bon pilote JDBC
			   Class.forName("com.mysql.jdbc.Driver") ;
			   System.out.println("Pilote JDBC pour MySql chargé");

				// établissement de la connexion
			   maCnx = DriverManager.getConnection("jdbc:mysql://localhost/tempofixe", "root", "root");
			   System.out.println("Etablissement connexion vers le serveur de données MySql réussie");
		}
		catch (ClassNotFoundException e) {
			System.err.println("Erreur chargement pilote JDBC pour MySql : "+ e.getMessage());
		}
		catch (SQLException e) {
			System.err.println("Erreur ouverture connexion vers le serveur MySql : " + e.getMessage());
		}
	}
	
	/**
	 * Termine la connexion à MySQL
	 */
	public void finalize(){
		if ( maCnx != null ) {
			try {
				maCnx.close();
			}
			catch (SQLException e){
				System.err.println("Erreur fermeture connexion MySQL");
			}
		}
		System.out.println("Connexion MySQL fermée");
		maCnx = null;
	}
	
	/**
	 * Fournit la liste de toutes les taches.
	 * 
	 * @return ArrayList<Tache>
	 * @see DaoTache
	 */
	@Override
	public ArrayList<Tache> getAll() {
		ArrayList<Tache> maListe = new ArrayList<Tache>();
		if (maCnx != null) {
			try {
				Statement st = maCnx.createStatement();
				String req = "select * from tache order by numtache";
				// on demande à exécuter cette requête
				ResultSet rs = st.executeQuery(req);

				// parcours de toutes les lignes du jeu d'enregistrements
				boolean ligneLue = rs.next();
				while (ligneLue) { // tant qu'il y a une ligne à lire

					Tache uneTache = getTache(rs);

					// ajout de la formation dans la collection
					maListe.add(uneTache);
					ligneLue = rs.next(); // lecture de la ligne suivante

				}
				rs.close(); // fermeture du jeu d'enregistrements
			} catch (SQLException e) {
				System.err.println("Erreur récupération des taches");
			}

		}
		return maListe;
	}
	
	/**
	 * Retourne une formation extraite de la base de données
	 * 
	 * @param rs
	 *            Le ResultSet qui contient les données
	 * @return la tache
	 * @throws SQLException
	 */
	private Tache getTache(ResultSet rs) throws SQLException {
		// construction d'une formation à partir de la ligne courante
		Tache uneTache;
		int unNumeroTache, unMatricule, uneReference, uneChargePrevi;
		String unLibelle;

		unNumeroTache = rs.getInt("numtache");
		unMatricule = rs.getInt("matricule");
		uneReference = rs.getInt("reference");
		uneChargePrevi = rs.getInt("chargeprevijourshomme");
		unLibelle = rs.getString("libelle");

		uneTache = new Tache(unNumeroTache, unLibelle, uneChargePrevi, unMatricule, uneReference);
		return uneTache;
	}

	/**
	 * Fournit une tache d'après son numero.
	 * 
	 * @param unNumTache
	 *            un Numero de tache
	 * @return Tache la tache
	 * @see DaoTache
	 */
	@Override
	public Tache getOne(int unNumTache) {
		Tache uneTache = null;
		if (maCnx != null) {
			try {
				String req = "select * from tache where numTache = ?";
				PreparedStatement st = maCnx.prepareStatement(req);
				st.setInt(1, unNumTache);
				// on demande à exécuter cette requête
				ResultSet rs = st.executeQuery();

				rs.next();
				uneTache = getTache(rs);
				rs.close();
			} catch (SQLException e) {
				System.err.println("Erreur récupération d'une tache");
			}			
		}
		return uneTache;
	}

	/**
	 * Crée la tache uneTache dans la base de données. La tache
	 * créée est retournée.
	 * 
	 * @param uneTache
	 *            la tache à créer
	 * @return Tache la tache créée
	 * @see DaoTache
	 */
	@Override
	public Tache create(Tache uneTache) {
		if (maCnx != null) {			
			try {
				String req = "insert into tache values (?, ?, ?, 1, ?, ?)";
				PreparedStatement st = maCnx.prepareStatement(req);
				st.setInt(1, uneTache.getNumTache());
				st.setInt(2, uneTache.getMatriculeCollaborateur());
				st.setInt(3, uneTache.getReferenceContrat());
				st.setString(4, uneTache.getLibelle());
				st.setInt(5, uneTache.getChargePreviJoursHomme());
				st.executeUpdate();				
			} catch (SQLException e) {
				System.err.println("Erreur création d'une tache");
				uneTache = null;
			}
		}
		return uneTache;
	}

	/**
	 * Met à jour de la tache uneTache dans la base. La tache
	 * modifiée est retournée.
	 * 
	 * @param uneTache
	 *            la Tache à modifier
	 * @return Tache la tache modifiée
	 * @see DaoTache
	 */
	@Override
	public Tache update(Tache uneTache) {
		if (maCnx != null) {			
			try {
				String req = "update tache set matricule = ?, reference = ?, libelle = ?, chargeprevijourshomme = ? where numtache = ?";
				PreparedStatement st = maCnx.prepareStatement(req);
				st.setInt(1, uneTache.getMatriculeCollaborateur());
				st.setInt(2, uneTache.getReferenceContrat());
				st.setString(3, uneTache.getLibelle());
				st.setInt(4, uneTache.getChargePreviJoursHomme());
				st.setInt(5, uneTache.getNumTache());
				st.executeUpdate();				
			} catch (SQLException e) {
				System.err.println("Erreur modification d'une tache");
				uneTache = null;
			}
		}
		return uneTache;
	}

	/**
	 * Supprime la tache uneTache dans la table tache
	 * 
	 * @param uneTache
	 *            la tache à supprimer
	 * @see DaoTache
	 */
	@Override
	public void delete(Tache uneTache) {
		try {
			String req = "delete from tache where numtache = ?";
			PreparedStatement st = maCnx.prepareStatement(req);
			int unNumTache = uneTache.getNumTache();
			st.setInt(1, unNumTache);			
			// on demande l'exécution de l'ordre de suppression
			st.executeUpdate();
		} catch (SQLException e) {
			System.err
					.println("Erreur exécution demande de suppression d'une tache");
		}
	}
	
	/**
	 * Utile pour générer automatiquement un numéro de tâche
	 * @return
	 */
	public int obtenirNumTacheMax() {
		int max = 0;
		if (maCnx!=null) {			
			try {				
				Statement st = maCnx.createStatement();
				String req = "select max(numtache) as max from tache";
				ResultSet rs = st.executeQuery(req);
				rs.next();
				max = rs.getInt("max");
				rs.close();
			} catch (SQLException e) {
				System.err.println("Erreur obtention numéro tâche maximal");
			}
		}
		return max;
	}
}
